home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / QD GX Shell / QuickDraw GX Shell - scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-14  |  9.7 KB  |  330 lines  |  [TEXT/KAHL]

  1. /**
  2.  --
  3.  --        App:        QuickDraw GX Shell
  4.  --
  5.  --        Version:    1.0     1/93:    added general QuickDraw GX support & scrolling     
  6.  --                    1.1        4/93:    added support for QuickDraw GX printing and testing to
  7.  --                                    see is QuickDraw GX is installed.
  8.  --
  9.  --        File:        QuickDraw GX - scroll.c
  10.  --
  11.  --
  12.  --        Comments:    This file contains all of the code required to maintain and adjust
  13.  --                    the scroll bars attached to the window. We also update the mapping of 
  14.  --                    our child viewPort as the user scrolls. This approach guarantees that 
  15.  --                    all of the shapes within our QuickDraw GX picture are drawn in their 
  16.  --                    correct locations after scrolling.
  17.  --
  18.  --                    You can search on "QuickDraw GX Scrolling" to find the additions which
  19.  --                    were added to support QuickDraw GX Scrolling.
  20.  --
  21.  --        Components:    QuickDraw GX Shell (main).c
  22.  --                    QuickDraw GX Shell (main).h
  23.  --                    QuickDraw GX Shell - print.c
  24.  --                    QuickDraw GX Shell - print.h
  25.  --                    QuickDraw GX Shell - scroll.c
  26.  --                    QuickDraw GX Shell - scroll.h
  27.  --                    QuickDraw GX Shell (main).π.rsrc
  28.  --
  29.  --
  30.  --        Notes:        1) Print this file in landscape for the best results
  31.  --                    2) If you are using THINK C v5.x, I have added markers to navigate the 
  32.  --                       code.
  33.  --                    3) This code was adapted and simplyified from the "DTS AE Skeleton" sample.
  34.  --
  35.  --
  36.  --        Author:        Pete "Luke" Alexander
  37.  --                    Developer Technical Support
  38.  --                    AppleLink: DEVSUPPORT
  39.  --
  40.  --        
  41.  --        ©1992 - 1993  Apple Computer, Inc. 
  42.  **/
  43.  
  44. #include <Windows.h>
  45.  
  46. #include "QuickDraw GX Shell (main).h"
  47. #include "QuickDraw GX Shell - scroll.h"
  48.  
  49. #include "graphics routines.h"
  50. #include "math routines.h"
  51.  
  52. extern     gxShape         gthePage;
  53. extern    gxViewPort        gcontentViewPort;
  54.  
  55. //
  56. // Internal Function Prototypes
  57. //
  58. void ResizeScrollBars(WindowPtr theWindow);
  59. void InvalidateScrollBars(WindowPtr theWindow);
  60. void DoControl(Point thePoint, ControlHandle theControl, short controlPart);
  61. pascal void DoControlButton(ControlHandle theControl, short controlPart);
  62. void DoScroll(WindowPtr theWindow, short hScroll, short vScroll);
  63. void AdjustScrollBar(ControlHandle theControl);
  64.  
  65. // Private global
  66. ControlActionUPP    gScrollProc = NewControlActionProc((ProcPtr)DoControlButton);
  67.  
  68.  
  69. /**----- ResizeScrollBars --------------------------------------------------------------------
  70.  --
  71.  --        This function is used when the window is resized. It resizes the scroll bars to match.
  72.  --
  73.  **/
  74. void ResizeScrollBars(WindowPtr theWindow)
  75. {    
  76.     MoveControl(((MyWindowPeek)theWindow)->vScrollBar,
  77.                 theWindow->portRect.right-(kScrollBarWidth-1),
  78.                 theWindow->portRect.top-1);
  79.     SizeControl(((MyWindowPeek)theWindow)->vScrollBar, kScrollBarWidth,
  80.                 theWindow->portRect.bottom-theWindow->portRect.top-
  81.                 (kScrollBarWidth-3));
  82.     MoveControl(((MyWindowPeek)theWindow)->hScrollBar,
  83.                 theWindow->portRect.left-1,
  84.                 theWindow->portRect.bottom-(kScrollBarWidth-1));
  85.     SizeControl(((MyWindowPeek)theWindow)->hScrollBar,
  86.                 theWindow->portRect.right-theWindow->portRect.left-
  87.                 (kScrollBarWidth-3), kScrollBarWidth);
  88.     
  89.     AdjustScrollBar(((MyWindowPeek)theWindow)->hScrollBar);    
  90.     AdjustScrollBar(((MyWindowPeek)theWindow)->vScrollBar);
  91. }
  92.  
  93.  
  94.  
  95. /**----- InvalidateScrollBars ----------------------------------------------------------------
  96.  --
  97.  --        This function is used to invalidate the area under the scroll bars for redrawing.  
  98.  --        The invalid area will be included in the next update event.
  99.  --
  100.  **/
  101. void InvalidateScrollBars(WindowPtr theWindow)
  102. {
  103.     Rect    tempRect;
  104.     
  105.     SetPort(theWindow);
  106.     
  107.     tempRect = theWindow->portRect;
  108.     tempRect.left = tempRect.right-(kScrollBarWidth-1);
  109.     InvalRect(&tempRect);
  110.     EraseRect(&tempRect);
  111.     
  112.     tempRect = theWindow->portRect;
  113.     tempRect.top = tempRect.bottom-(kScrollBarWidth-1);
  114.     InvalRect(&tempRect);
  115.     EraseRect(&tempRect);
  116. }
  117.  
  118.  
  119.  
  120. /**----- DoControl ---------------------------------------------------------------------------
  121.  --
  122.  --        This function is used when the mouse is clicked on one of the scroll bars in a document. 
  123.  --
  124.  **/
  125. void DoControl(Point thePoint, ControlHandle theControl, short controlPart)
  126. {
  127.     short        oldValue;
  128.     short        amountToScroll;
  129.     WindowPtr    theWindow;
  130.     
  131.     switch (controlPart)
  132.     {
  133.     case inUpButton:
  134.     case inDownButton:
  135.     case inPageUp:
  136.     case inPageDown:
  137.         TrackControl(theControl, thePoint, gScrollProc);
  138.         break;
  139.     case inThumb:
  140.         oldValue = GetCtlValue(theControl);
  141.         if (TrackControl(theControl, thePoint, (ControlActionUPP)nil));
  142.         {
  143.             amountToScroll = - (GetCtlValue(theControl) - oldValue);
  144.             theWindow = (**theControl).contrlOwner;
  145.             if (((MyWindowPeek)theWindow)->hScrollBar == theControl)    /* horizontal? */
  146.                 DoScroll(theWindow, amountToScroll, 0);
  147.             else
  148.                 DoScroll(theWindow, 0, amountToScroll);
  149.             AdjustScrollBar(theControl);
  150.         }
  151.         break;
  152.     }
  153.     
  154. }
  155.  
  156.  
  157.  
  158. /**----- DoControlButton ---------------------------------------------------------------------
  159.  --
  160.  --        This is the actionProc for the first call to TrackControl in DoControl.  This routine
  161.  --         is called by the operating system while the mouse button is being held on the UpButton, 
  162.  --        DownButton, PageUp, and PageDown areas.  It updates the window and scroll bars.
  163.  --
  164.  **/
  165. pascal void DoControlButton(ControlHandle theControl, short controlPart)
  166. {
  167.     WindowPtr    theWindow;
  168.     long        percent;
  169.     long        direction;
  170.     short        amountToScroll;
  171.     short        theMax, theValue;
  172.  
  173.     switch (controlPart)
  174.     {
  175.     case inUpButton:
  176.         percent = 15;
  177.         direction = 1;
  178.         break;
  179.     case inDownButton:
  180.         percent = 15;
  181.         direction = -1;
  182.         break;
  183.     case inPageUp:
  184.         percent = 90;
  185.         direction = 1;
  186.         break;
  187.     case inPageDown:
  188.         percent = 90;
  189.         direction = -1;
  190.         break;
  191.     default:
  192.         return;        /* IMPORTANT:  controlPart will often be zero - take no action! */
  193.     }    
  194.  
  195.     theWindow = (**theControl).contrlOwner;
  196.     
  197.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal */
  198.         amountToScroll = (short)((long)(theWindow->portRect.right -
  199.                                         theWindow->portRect.left -
  200.                                         (kScrollBarWidth-1)) *
  201.                                         percent/100 * direction);
  202.     else                                                        /* Vertical */
  203.         amountToScroll = (short)((long)(theWindow->portRect.bottom -
  204.                                         theWindow->portRect.top -
  205.                                         (kScrollBarWidth-1)) *
  206.                                         percent/100 * direction);
  207.  
  208.     theValue = GetCtlValue(theControl);
  209.     theMax = GetCtlMax(theControl);
  210.  
  211.     /* Don't allow scrolling past limits */
  212.     if (amountToScroll < 0)        /* scrolling right or down */
  213.     {
  214.         if ((theValue + -amountToScroll) > theMax)
  215.             amountToScroll = - (theMax - theValue);
  216.     }
  217.     else    /* scrolling left or up */
  218.     {
  219.         if ((theValue + -amountToScroll) < 0)
  220.             amountToScroll = theValue;
  221.     }
  222.  
  223.     /* Scroll the contents of the window */
  224.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal */
  225.         DoScroll(theWindow, amountToScroll, 0);
  226.     else                                                        /* Vertical */
  227.         DoScroll(theWindow, 0, amountToScroll);
  228.  
  229.     AdjustScrollBar(theControl);
  230. }
  231.  
  232.  
  233.  
  234. /**----- DoScroll ----------------------------------------------------------------------------
  235.  --
  236.  --        This procedure scrolls the contents of a document window an amount specified in
  237.  --        hScroll and vScroll, and fills the empty space created. We also adjust the mapping 
  238.  --        of our child viewPort - "gcontentViewPort". This ensures that all of our shapes
  239.  --        are drawn in the correct location after the scrolling.
  240.  --
  241.  **/
  242.  void DoScroll(WindowPtr theWindow, short hScroll, short vScroll)
  243. {
  244.     Rect            scrollRect;
  245.     Point            scrollPt;
  246.     RgnHandle        myRgn;
  247.     gxMapping        viewPortMapping;
  248.     
  249.     if ((hScroll == 0) && (vScroll == 0)) return;
  250.  
  251.     //
  252.     //    The user has scrolled the contents of the window, therefore we need
  253.     //    to update the mapping of the "gcontentViewPort" to reflect this change.
  254.     //    If we did not adjust the mapping or transform of all of our shape(s) on
  255.     //    the page, they would be redrawn in their original unscrolled location
  256.     //    because the geometry of each shape has not been changed.        
  257.     //   
  258.     //    We get the mapping of "gcontentViewPort", and adjust the mapping for the
  259.     //    scroll amount. We will then reset the mapping. The "ff" macro converts
  260.     //    an integer to their fixed point equivalents.                (QuickDraw GX Scrolling)
  261.     //                                                                 
  262.     GXGetViewPortMapping(gcontentViewPort, &viewPortMapping);
  263.  
  264.     MoveMapping(&viewPortMapping, ff(hScroll), ff(vScroll));
  265.  
  266.     GXSetViewPortMapping(gcontentViewPort, &viewPortMapping);
  267.  
  268.  
  269.     /* Scroll contents of window except for scroll bars */
  270.     scrollRect = theWindow->portRect;
  271.     scrollRect.right -= (kScrollBarWidth-1);
  272.     scrollRect.bottom -= (kScrollBarWidth-1);
  273.  
  274.     SetPort(theWindow);
  275.     myRgn = NewRgn();
  276.     
  277.     ScrollRect(&scrollRect, hScroll, vScroll, myRgn);
  278.     SetPt(&scrollPt, hScroll, vScroll);
  279.  
  280.     AddPt(scrollPt, &((MyWindowPeek)theWindow)->origin);
  281.  
  282.     DrawWindow(theWindow);
  283.  
  284.     DisposeRgn(myRgn);
  285. }
  286.  
  287.  
  288.  
  289. /**----- AdjustScrollBar ---------------------------------------------------------------------
  290.  --
  291.  --        This function looks at the current state of the window, and adjusts the maximum, 
  292.  --        minimum, and current values for both scroll bars.
  293.  --
  294.  **/
  295. void AdjustScrollBar(ControlHandle theControl)
  296. {
  297.     WindowPtr    theWindow;
  298.     Rect        picFrame;
  299.     short        delta1, delta2;
  300.     short        theMax;
  301.  
  302.     theWindow = (**theControl).contrlOwner;
  303.     picFrame = ((MyWindowPeek)theWindow)->documentBoundsRect;
  304.     OffsetRect(&picFrame, -picFrame.left, -picFrame.top);        /* Adjust upper left to 0,0 */
  305.  
  306.     if (theControl == ((MyWindowPeek)theWindow)->hScrollBar)    /* Horizontal scroll bar */
  307.     {
  308.         delta1 = - theWindow->portRect.left - ((MyWindowPeek)theWindow)->origin.h;
  309.         delta2 = - delta1 + picFrame.right - (theWindow->portRect.right -
  310.                  theWindow->portRect.left - (kScrollBarWidth-1));
  311.     }
  312.     else    /* Vertical scroll bar */
  313.     {
  314.         delta1 = - theWindow->portRect.top - ((MyWindowPeek)theWindow)->origin.v;
  315.         delta2 = - delta1 + picFrame.bottom - (theWindow->portRect.bottom -
  316.                  theWindow->portRect.top - (kScrollBarWidth-1));
  317.     }
  318.     
  319.     theMax = 0;
  320.     if (delta1 > 0) theMax += delta1;
  321.     if (delta2 > 0) theMax += delta2;
  322.     
  323.     if (theMax > 0)
  324.     {
  325.         SetCtlMax(theControl, theMax);
  326.         SetCtlValue(theControl, delta1);
  327.     }
  328.     else
  329.         SetCtlMax(theControl, 0);
  330. }